package main

import (
	"errors"
	"fmt"
	"io"
	"os"
	"reflect"
)

type Persion struct {
	Name string
	Age  int
}

func (this *Persion) Do(par string) {
	fmt.Println("do nothing:" + par)
}

func func1() {
	var s struct {
		W io.Writer
	}

	s.W = os.Stdout
	// func ValueOf(i interface{}) Value
	// ValueOf返回一个初始化为i接口保管的具体值的Value，ValueOf(nil)返回Value零值
	fmt.Println("ValueOf:", reflect.ValueOf(&s).Elem())
	// func Indirect(v Value) Value
	// reflect.Indirect 返回v持有的指针指向的值的Value。如果v持有nil指针，会返回Value零值；如果v不持有指针，会返回v
	fmt.Println("Indirect:", reflect.Indirect(reflect.ValueOf(&s)))
	fmt.Println("Field(0):", reflect.Indirect(reflect.ValueOf(&s)).Field(0))
	fmt.Println("Interface():", reflect.Indirect(reflect.ValueOf(&s)).Field(0).Interface())
	v := reflect.Indirect(reflect.ValueOf(&s)).Field(0).Interface()
	if v != s.W.(interface{}) {
		errors.New(fmt.Sprintf("Interface() on interface: ", v, s.W))
	}
}
func func2() {
	s := &Persion{
		Name: "zhangsan",
		Age:  24,
	}
	fmt.Println("ValueOf:", reflect.ValueOf(&s))
	fmt.Println("ValueOf:", reflect.ValueOf(&s).Type())
	fmt.Println("Indirect:", reflect.Indirect(reflect.ValueOf(&s)))
	fmt.Println("Indirect:", reflect.Indirect(reflect.ValueOf(&s)).Type())
	fmt.Println("TypeOf:", reflect.TypeOf(s))
	rg := []reflect.Value{reflect.ValueOf("222")}
	fmt.Println("MethodByName:", reflect.Indirect(reflect.ValueOf(&s)).MethodByName("Do").Call(rg))
}
func main() {
	func2()
}
